// SubCommodity.js
import { Util } from '../../utils/util.js';
import { Definition } from '../common/definition.js';
import { CommodityCategory } from '../basicData/commodityCategory.js';
import { MeasurementUnit } from '../basicData/measurementUnit.js';
import { CsDouble } from '../common/csDouble.js';
import { CsFundDouble } from '../common/csFundDouble.js';
import { SubCommodityWarehouseInventoryData } from './subcommodityWarehouseInventoryData.js';
import { TestConfig } from '../common/testConfig.js';

// 委外加工状态
export const SubCommodityMetalFilterTypeEnum = {
    AllMetal: 0,  // 所有贵金属商品
    MetalSelfOnly: 1, // 贵金属自身
    MetalRelatedOnly: 2, // 非贵金属自身的贵金属商品, 
    NoneMetal: 3,        // 非贵金属以外的商品
};

export class SubCommodityFilter{

        // 贵金属类型过滤
        metalType = null;
        constructor({metalType = null}={}) {
            this.metalType = metalType;
        }
        // 清空
        clear() {
            this.metalType = null;
        }

        // 克隆
        static clone(filter) {
            const ret = new SubCommodityFilter();
            ret.metalType = filter.metalType;
            return ret;
        }

        toJson() {
            const ret = {};
            if (this.metalType !== null) {
                ret.ign_metalType = this.metalType;
            }
            return ret;
        }
}

export class SubCommodity {
    constructor({
        id = '',
        code = '',
        commodityId = '',
        standard = '',
        commodity = null,
        imgs = '',
        name = '',
        qrCode = '',
        cost = 0,
        purchasePrice = 0,
        retailPrice = 0,
        wholesalePrice = 0,
        remark = '',
        unit = null,
        category = null,
        enabled = true,
        inventoryData = [],  // List<SubCommodityWarehouseInventoryData>
        metalAccountTypeId = null, // 关联贵金属账户类型ID
        metalCode = null,          // 商品贵金属code
        isMetalSelf = false,       // 贵金属自身，如果是所有操作会直接影响 metalAccountTypeId 指定的账户，和库存。
        sorder = 0,
    } = {}) {
        this.id = id;
        this.code = code;
        this.qrCode = qrCode;
        this.enabled = enabled;
        this._imgs = imgs;
        this.standard = standard;
        this.name = name;
        this.commodity = commodity;
        this.commodityId = commodityId;
        this.coverImgCachePath = '';
        this.cost = new CsFundDouble(cost);
        this.inventoryData = inventoryData;
        this.purchasePrice = new CsFundDouble(purchasePrice);
        this.retailPrice = new CsFundDouble(retailPrice);
        this.wholesalePrice = new CsFundDouble(wholesalePrice);
        this.remark = remark;
        this._unit = unit;
        this.selected = false;
        this._category = category;
        this.metalAccountTypeId = metalAccountTypeId; // 关联贵金属账户类型ID
        this.metalCode = metalCode;          // 商品贵金属code      
        this.isMetalSelf = isMetalSelf; 
        this.sorder = sorder; 
    }

    static empty() {
        return new SubCommodity();
    }

    static clone(subCommodity) {
        const clone = new SubCommodity({
            id: subCommodity.id,
            code: subCommodity.code,
            commodityId: subCommodity.commodityId,
            standard: subCommodity.standard,
            commodity: subCommodity.commodity,
            imgs: subCommodity._imgs,
            name: subCommodity.name,
            qrCode: subCommodity.qrCode,
            purchasePrice: subCommodity.purchasePrice.value,
            retailPrice: subCommodity.retailPrice.value,
            wholesalePrice: subCommodity.wholesalePrice.value,
            cost: subCommodity.cost.value,
            remark: subCommodity.remark,
            unit: subCommodity._unit,
            category: subCommodity._category,
            enabled: subCommodity.enabled,
            metalAccountTypeId: subCommodity.metalAccountTypeId,
            metalCode: subCommodity.metalCode,
            isMetalSelf: subCommodity.isMetalSelf,
            sorder: subCommodity.sorder
        });

        if (subCommodity.inventoryData) {
            clone.inventoryData = subCommodity.inventoryData.map(item => SubCommodityWarehouseInventoryData.clone(item));
        }

        return clone;
    }

    get imgs() {
        if (TestConfig.commodityDataTest) {
            return this._imgs || "";
        }
        else {
            return this._imgs === '' ? '' : Definition.baseUrlWithoutService + this._imgs;
        }
    }

    set imgs(value) {
        this._imgs = value;
    }

    clearImg() {
        this.coverImgCachePath = '';
        this._imgs = '';
    }

    get unit() {
        const ret = this.commodity?.unit;
        return (ret || this._unit) || MeasurementUnit.empty();
    }

    set unit(value) {
        this._unit = value;
    }

    get category() {
        if (this.commodity) return this.commodity.category;
        if (this._category) return this._category;
        return CommodityCategory.empty();
    }

    getTotalInventory(includeWareHouses) {
        let value = 0;
        if (this.inventoryData) {
            for (const item of this.inventoryData) {
                if (includeWareHouses && !includeWareHouses.some(e => e.id === item.warehouseId)) {
                    continue;
                }
                value += item.count.value;
            }
        }
        return value;
    }

    getInventoryDataByWarehouse(wareHouses) {
        const ret = [];
        for (const item of wareHouses) {
            if (this.inventoryData) {
                const find = this.inventoryData.find(e => e.warehouseId === item.id) ||
                    new SubCommodityWarehouseInventoryData({
                        count: CsDouble.zero(),
                        warehouseId: item.id,
                        warehouseName: item.name,
                        storeId: item.store?.id || '',
                        storeName: item.store?.name || '',
                        subCommodityId: this.id
                    });
                ret.push(find);
            } else {
                ret.push(new SubCommodityWarehouseInventoryData({
                    count: CsDouble.zero(),
                    warehouseId: item.id,
                    warehouseName: item.name,
                    storeId: item.store?.id || '',
                    storeName: item.store?.name || '',
                    subCommodityId: this.id
                }));
            }
        }
        return ret;
    }

    syncInventoryDataByWarehouse(data) {
        if (!this.inventoryData) {
            this.inventoryData = data.filter(item => item.count.value !== 0);
        } else {
            for (const item of data) {
                if (item.count.value !== 0 && !this.inventoryData.includes(item)) {
                    this.inventoryData.push(item);
                }
            }
        }
    }

    static fromJson(json) {

        const instance = new SubCommodity({
            id: Util.jsonToString(json.id),
            imgs: Util.jsonToString(json.specImgs),
            standard: Util.jsonToString(json.specName),
            name: Util.jsonToString(json.commodityName),
            commodityId: Util.jsonToString(json.commodityId),
            qrCode: Util.jsonToString(json.commodityBarcode),
            code: Util.jsonToString(json.commodityCode),
            enabled: Util.jsonToBool(json.useState, true),
            cost: Util.jsonToDouble(json.commodityCostOne, 0),
            purchasePrice: Util.jsonToDouble(json.lineCostPrice, 0),
            retailPrice: Util.jsonToDouble(json.lineRetailPrice, 0),
            wholesalePrice: Util.jsonToDouble(json.lineTradePrice, 0),
            remark: Util.jsonToString(json.remark),
            unit: MeasurementUnit.fromJsonValue({
                id: json.commodityUnitId,
                name: json.unitName,
                supportDecimal: json.decimalSupport
            }),
            category: new CommodityCategory(
                Util.jsonToString(json.commodity_category_id),
                Util.jsonToString(json.commodityCategoryName)
            ),
            metalAccountTypeId: Util.jsonToString(json.metalAccountTypeId),
            metalCode: Util.jsonToString(json.metalCode),
            isMetalSelf: Util.jsonToBool(json.isMetalSelf, false),
            sorder: Util.jsonToInt(json.sorder, 0)
        });

        if (json.inventoryInfo) {
            instance.inventoryData = json.inventoryInfo.map(item => SubCommodityWarehouseInventoryData.fromJson(item));
        }

        //console.log(`SubCommodity.cost = ${instance.cost.value}`);

        return instance;
    }

    static fromSalesData(json) {
        return new SubCommodity({
            id: Util.jsonToString(json.commonditySpecId),
            imgs: Util.jsonToString(json.specImgs),
            standard: Util.jsonToString(json.specName),
            name: Util.jsonToString(json.commodityName),
            commodityId: Util.jsonToString(json.commodityId),
            qrCode: Util.jsonToString(json.commodityBarcode),
            code: Util.jsonToString(json.commodityCode),
            cost: Util.jsonToDouble(json.cost, 0),
            purchasePrice: Util.jsonToDouble(json.lineCostPrice, 0),
            retailPrice: Util.jsonToDouble(json.lineRetailPrice, 0),
            wholesalePrice: Util.jsonToDouble(json.lineTradePrice, 0),
            remark: Util.jsonToString(json.remark),
            enabled: true,
            unit: new MeasurementUnit(
                Util.jsonToString(json.commodityUnitId),
                Util.jsonToString(json.commodityUnit),
                Util.jsonToBool(json.decimalSupport, false)
            ),
            category: new CommodityCategory(
                Util.jsonToString(json.commodity_category_id),
                Util.jsonToString(json.commodityCategoryName)
            ),
            metalAccountTypeId: Util.jsonToString(json.metalAccountTypeId),
            metalCode: Util.jsonToString(json.metalCode),
            isMetalSelf: Util.jsonToBool(json.isMetalSelf, false)
        });
    }

    static fromInventorySheetJson(json) {
        return new SubCommodity({
            id: Util.jsonToString(json.specId),
            name: Util.jsonToString(json.commodityName),
            imgs: Util.jsonToString(json.specImgs),
            standard: Util.jsonToString(json.specName),

            commodityId: Util.jsonToString(json.commodityId),
            qrCode: Util.jsonToString(json.commodityBarcode),
            unit: MeasurementUnit.fromJsonValue({
                id: json.unitId,
                name: json.unitName,
                supportDecimal: Util.jsonToBool(json.decimalSupport, false)

            }),
            purchasePrice: Util.jsonToDouble(json.lineCostPrice, 0),
            retailPrice: Util.jsonToDouble(json.retailPrice, 0),
            wholesalePrice: Util.jsonToDouble(json.lineTradePrice, 0),
            imgs: Util.jsonToString(json.specImgs),
            metalAccountTypeId: Util.jsonToString(json.metalAccountTypeId),
            metalCode: Util.jsonToString(json.metalCode),
            isMetalSelf: Util.jsonToBool(json.isMetalSelf, false)
        })
    }

    equal(commodity) {
        return (
            this.code === commodity.code &&
            this.name === commodity.name &&
            this.qrCode === commodity.qrCode &&
            this._imgs === commodity._imgs &&
            this.standard === commodity.standard &&
            this.commodityId === commodity.commodityId &&
            this.remark === commodity.remark &&
            this.purchasePrice.equals(commodity.purchasePrice) &&
            this.retailPrice.equals(commodity.retailPrice) &&
            this.wholesalePrice.equals(commodity.wholesalePrice)
        );
    }

    toJson() {
        const ret = {};
        if (this.id !== '') {
            ret.id = this.id;
        } else {
            ret.commodityCostOne = this.cost.value;
        }
        ret.commodityCode = this.code;
        ret.commodityName = this.name;
        ret.specName = this.standard;
        ret.commodityImgs = this._imgs;
        ret.commodityBarcode = this.qrCode;
        ret.useState = this.enabled ? 1 : 2;
        ret.specImgs = this._imgs;
        if (this.commodityId !== '') {
            ret.commodityId = this.commodityId;
        }
        ret.lineCostPrice = this.purchasePrice.value;
        ret.lineRetailPrice = this.retailPrice.value;
        ret.lineTradePrice = this.wholesalePrice.value;
        ret.remark = this.remark;

        ret.metalAccountTypeId = this.metalAccountTypeId;
        ret.metalCode = this.metalCode;
        ret.isMetalSelf = this.isMetalSelf ? 1 : 0;
        ret.sorder = this.sorder;

        if (this.inventoryData && this.id === '') {
            ret.initInventoryInfo = this.inventoryData.map(item => ({
                count: item.count.value,
                storageId: item.warehouseId,
                specId: item.subCommodityId,
                storeId: item.storeId
            }));
        }

        return ret;
    }

    // 对象传递拷贝 与  fromJson 一一对应
    toCopyJson() {
        return {
            id: this.id,
            specImgs: this._imgs,
            specName: this.standard,
            commodityName: this.name,
            commodityId: this.commodityId,
            commodityBarcode: this.qrCode,
            commodityCode: this.code,
            useState: this.enabled ? "true" : "false",
            commodityCostOne: this.cost.value,
            lineCostPrice: this.purchasePrice.value,
            lineRetailPrice: this.retailPrice.value,
            lineTradePrice: this.wholesalePrice.value,
            remark: this.remark,
            unitName: this.unit?.name,
            commodityUnitId: this.unit?.id,
            decimalSupport: this.unit?.supportDecimal,
            commodity_category_id: this.category?.id,
            commodityCategoryName: this.category?.name,
            inventoryInfo: this.inventoryData
                ? this.inventoryData.map(item => item.toCopyJson?.() || item)
                : undefined,
            metalAccountTypeId: this.metalAccountTypeId,
            metalCode: this.metalCode,
            isMetalSelf: this.isMetalSelf
        };
    }

    /// 同步商品信息，用于无多规格时的商品
    syncCommodityInfo(commodity) {
        this._imgs = commodity.coverRelationPath;
        this.name = commodity.name;
        this.code = commodity.code;
        this.qrCode = commodity.qrCode;
        this.standard = commodity.standard;
        this.cost = commodity.cost;

        // 价格
        this.purchasePrice = commodity.purchasePrice;
        this.retailPrice = commodity.retailPrice;
        this.wholesalePrice = commodity.wholesalePrice;

        // 如果商品未启用，则子商品也不启用
        if (!commodity.enabled) {
            this.enabled = commodity.enabled;
        }

        this.remark = commodity.remark;

        /// 初始库存
        this.inventoryData = commodity.initInventory;

        this.metalAccountTypeId = commodity.metalAccountTypeId;
        this.metalCode = commodity.metalCode;
        this.isMetalSelf = commodity.isMetalSelf;
        this.sorder = commodity.sorder;
    }
}
